var Socket = require("socket").Socket;
var Buffer = require("binary").Buffer;

var LNHTTPRequest=require("standalone/HTTPRequest").LNHTTPRequest;

/**
 * Class: LNHTTPClient
 */
function LNHTTPClient(options)
{
	this.socket=options.socket;
	this.app=options.app;
	this.server=options.server;
	this.comet=options.comet;
}

/**
 * Method: who
 *		idiotic method. answers "LNHTTPClient"
 */
LNHTTPClient.prototype.who=function()
{
	return "LNHTTPClient";
}

/**
 * Method: action
 *		Called each time socket has anything to do
 *
 * Returns:
 *		0 - if okay
 * 		1 - if client is dead
 */
LNHTTPClient.prototype.action=function()
{
	var buffer = this.socket.receive(5000);
	system.stdout.writeLine("LNHTTPClient.action() - got some data - "+(buffer?(buffer.length+" bytes"):"undefined"));
	if (!buffer) return 1;
	if (buffer.length==0) return 1;

	var oldlength;
	if (this.buffer) {
		oldlength=this.buffer.length;
		var b=new Buffer(this.buffer.length+buffer.length);
		b.copyFrom(this.buffer,0,0,this.buffer.length);
		b.copyFrom(buffer,0,this.buffer.length,this.buffer.length+buffer.length);
		this.buffer=b;
	} else {
		this.buffer=buffer;
		oldlength=0;
	}
	var searchpos=oldlength-3;
	if (searchpos<0) searchpos=0;
	searchpos=0;// TODO

	var cycling=1;
	var r=0,ret=-1,done_some=0;
	while (cycling) {
		if (this.request) {
			// r=0 means "please disconnect"
			// r=1 means "OK"
			// r=2 means "still waiting"
			// r=3 means long polling
			var r=this.request.work_pending(this);
			system.stdout.writeLine("  LNHTTPClient.prototype.action() - request.work_pending() result = "+r);
			searchpos=0;
			if (r==0) {cycling=false;ret=1;}
			if (r==1) {cycling=true;delete this.request;done_some=1;}
			if (r==2) {cycling=false;ret=0;}
			if (r==3) {cycling=false;ret=0;}
		} else {
			// r=0 means "nothing found"
			// r=1 means "OK, next"
			// r=2 means "disconnect"
			// r=3 means "multipart"
			// r=4 means "long polling"
			var r=this.search_work(searchpos);
			system.stdout.writeLine("  LNHTTPClient.prototype.action() - work() result = "+r);
			searchpos=0;
			if (r==0) {cycling=false;ret=0;}
			if (r==1) {cycling=true;done_some=1;}
			if (r==2) {cycling=false;ret=1;}
			if (r==3) {cycling=true;}
			if (r==4) {cycling=false;ret=0;}
		}
	}
	system.stdout.writeLine("  LNHTTPClient.prototype.action() - work() as is, done_some="+done_some+", ret="+ret);
	if (done_some) return 1;
	return ret;
}

/**
 * Method: search_work
 *		searches for \r\n\r\n or \n\n starting from position searchpos
 *		if found, does http work and removes data from this.buffer
 *
 * Returns:
 *		0 - nothing found
 *		1 - found and ok
 *		2 - some error, please close connection
 *		3 - multipart
 */


LNHTTPClient.prototype.search_work=function(searchpos)
{
	system.stdout.writeLine("  LNHTTPClient.search_work() - searchpos="+searchpos+", this.buffer.length="+this.buffer.length);
//	for (var j=0;j<this.buffer.length;j++) system.stdout.write(this.buffer[j]+" ");
//	system.stdout.write("\n");
	for (var j=0;j<this.buffer.length-3;j++) {
		if (this.buffer[j]==13 && this.buffer[j+1]==10 && this.buffer[j+2]==13 && this.buffer[j+3]==10) return this.work(j);
	}
	return 0;
}

/**
 * Method: work
 *
 * Returns:
 *		0 - 
 *		1 - ok
 *		2 - some error, please close connection
 *		3 - multipart
 *		4 - long polling
 */

/*
GET /wiki/страница HTTP/1.1
Host: ru.wikipedia.org
User-Agent: Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9b5) Gecko/2008050509 Firefox/3.0b5
Accept: text/html
Connection: close
*/
LNHTTPClient.prototype.work=function(len)
{
	var t=this;
	system.stdout.writeLine("LNHTTPClient.work("+len+")");
	var b=new Buffer(this.buffer,0,len+2,false);// Shared memory

	this.request=new LNHTTPRequest({socket:this.socket,app:this.app,comet:this.comet,server:this.server});
	var pos=0;
	for (var i=0;i<b.length-1;i++) {
		if (b[i]==13 && b[i+1]==10) {
			// FULL LINE  pos ... i
			if (pos==0) this.request.parse_first_line(b,pos,i); else this.request.parse_header(b,pos,i);
			pos=i+2;
		}
	}
	// r=0 means "please disconnect"
	// r=1 means "OK"
	// r=2 means "still waiting"
	// r=3 means long polling
	var ret=this.request.work();
	system.stdout.writeLine("LNHTTPClient.work() - request.work() returned "+ret);
	b=undefined;
	// Truncating buffer
	this.buffer=new Buffer(this.buffer,len+4,this.buffer.length);
	switch (ret) {
		case 0:
			return 2;
		case 1:
			delete this.request;
			return 1;
		case 2:
			return 3;
		case 3:
			return 4;
	}
	return -1;
}


exports.LNHTTPClient=LNHTTPClient;
